package designpattern;

import java.util.ArrayList;
import java.util.List;

/**
 * 建造者模式实现
 * 1. 简介
 * 使用多个简单的对象构建成一个复杂的对象
 * 三个角色：建造者、具体的建造者、监工、使用者（严格来说不算）
 * 建造者角色：定义生成实例所需要的所有方法；
 * 具体的建造者角色：实现生成实例所需要的所有方法，并且定义获取最终生成实例的方法；
 * 监工角色：定义使用建造者角色中的方法来生成实例的方法；
 * 使用者：使用建造者模式。
 * 2. 优点
 * (1) 建造者独立,易拓展
 * (2) 便于控制细节风险
 * 3. 缺点
 * (1) 产品必须有共同点，范围有限制
 * (2) 内部变化复杂时，会有很多建造类
 * 4. 注意
 * 与工厂模式的区别：建造者更加关注与零件装配的顺序
 * 5. 实现步骤
 * // 1. 创建一个食物条目和事物包装的接口Item，Packing
 * // 2. 实现packing接口（Wrapper包装纸，Bottle包装瓶）
 * // 3. 实现Item接口（Burger汉堡类,ColdDrink可乐类）
 * // 4. 拓展 Burger和ColdDrink类
 * // 5. 5. 定义一个套餐类的构造器
 * // 6. 创建套餐类
 */
public class BuildTest {
    public static void main(String[] args) {
        // 1. 创建一个食物条目和事物包装的接口Item，Packing
        // 2. 实现packing接口（Wrapper包装纸，Bottle包装瓶）
        // 3. 实现Item接口（Burger汉堡类,ColdDrink可乐类）
        // 4. 拓展 Burger和ColdDrink类
        // 5. 5. 定义一个套餐类的构造器
        // 6. 创建套餐类
        MealBuilder mealBuilder = new MealBuilder();
        Meal meal = mealBuilder.prepareVegMeal();
        System.out.println("套餐地址: " + meal);
        // 查看套餐内容
        meal.showItem();
        // 输出套餐价格
        System.out.println("套餐价格: " + meal.getCost());

    }
}

// 创建者角色
interface Item {
    String name();

    float price();

    Packing packing();

}

interface Packing {
    String pack();
}

// 包装纸
class Wrapper implements Packing {

    @Override
    public String pack() {
        return "Wrapper";
    }
}

// 包装瓶
class Bottle implements Packing {

    @Override
    public String pack() {
        return "Bottle";
    }
}

// 具体的建造者角色(汉堡类)
abstract class Burger implements Item {
    @Override
    public abstract float price();

    @Override
    public abstract String name();

    @Override
    public Packing packing() {
        return new Wrapper();
    }
}

// 具体的建造者角色(可乐类)
abstract class ColdDrink implements Item {

    @Override
    public Packing packing() {
        return new Bottle();
    }

    @Override
    public abstract float price();

    @Override
    public abstract String name();
}

// 实体构造器
class VegBurger extends Burger {

    @Override
    public float price() {
        return 25.0f;
    }

    @Override
    public String name() {
        return "Veg Burger";
    }
}


class Coke extends ColdDrink {

    @Override
    public float price() {
        return 30.0f;
    }

    @Override
    public String name() {
        return "Coke";
    }
}

//监工角色
class Meal {
    private List<Item> items = new ArrayList<Item>();

    public void addItem(Item item) {
        items.add(item);
    }

    // 计算价格
    public float getCost() {
        float cost = 0f;
        for (Item item : items) {
            cost += item.price();
        }
        return cost;
    }

    // 查看套餐详情
    public void showItem() {
        for (Item item : items) {
            System.out.print("Item : " + item.name());
            System.out.print(", Packing : " + item.packing().pack());
            System.out.println(", Price : " + item.price());
        }
    }
}

// 使用者(使用建造者模式)
class MealBuilder {
    public Meal prepareVegMeal() {
        Meal meal = new Meal();
        meal.addItem(new VegBurger());
        meal.addItem(new Coke());
        return meal;
    }
}